// #include <iostream>
// #include <string>
// #include <vector>
// int main()
// {
// 	std::string s1 = "nihao";
// 	std::string s2 = "niyehao";
// 	std::vector<std::string> vec1 {	s1, s2 };
// 	std::vector<std::string> vec2 = { s1, s2 };
// }

// #include <iostream>
// int main()
// {
// 	int k { 1 };
// 	int arr[] {1, 2, 3, 4, 5, 6, 7, 8};
// 	std::cout << k << std::endl;
// 	for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
// 	{
// 		std::cout << arr[i] << " ";
// 	}
//     std::cout << std::endl;
// 	return 0;
// }

// #include <iostream>
// #include <string>
// #include <vector>
// #include <unordered_map>

// struct _example
// {
// 	_example(std::string s, std::vector<int> v, int _a, std::unordered_map<int, int> m)
// 		:str(s), vec(v), a(_a), mp(m)
// 	{
// 	}
// 	std::string str;
// 	std::vector<int> vec;
// 	int a;
// 	std::unordered_map<int, int> mp;
// };

// int main()
// {
// 	int a { 10 };
// 	std::string str { "nihao" };
// 	std::vector<int> vec { 1, 2, 3, 4, 5, 6, 7, 8 };
// 	std::pair<int, int> p{1, 1};
// 	std::unordered_map<int, int> mp { p };
// 	_example exa { str, vec, a, mp };
// 	std::cout << exa.str << std::endl;
// 	for (int i = 0; i < exa.vec.size(); i++)
// 	{
// 		std::cout << exa.vec[i] << " ";
// 	}
// 	std::cout << std::endl;
// 	std::cout << exa.a << std::endl;
// 	auto it = exa.mp.begin();
// 	if (it != exa.mp.end())
// 	{
// 		std::cout << it->first << ":" << it->second << std::endl;
// 	}

// 	return 0;
// }

// #include <iostream>
// #include <string>
// int main()
// {
// 	int a = 0;
// 	auto b = a;
// 	std::string str = "nihao";
// 	auto str2 = str;
// 	std::cout << b << " : " << str2 << std::endl;
// 	return 0;
// }

// #include <iostream>
// #include <string>
// int main()
// {
// 	int a = 10;
// 	decltype(a) b = a;
// 	decltype(b) c;
// 	c = a;

// 	std::cout << b << " " << c << std::endl;
// 	return 0;
// }
// #include <iostream>

// int main()
// {
//     int &a = 1;

//     return 0;
// }

// struct exam
// {
//     exam(int e = 0)
//         :_e(e)
//     {}
//     int _e;
// };

// #include <iostream>
// int main()
// {
//     const int &a = int(4);
//     const exam &e = exam(10);

//     std::cout << a << ":" << e._e << std::endl;

//     int &&a = int(1);
//     auto pa = &a;
//     std::cout << pa << std::endl;
//     int b = 0;

//     return 0;
// }

// #include <iostream>
// #include <vector>
// using namespace std;
// vector<vector<int>> Test1()
// {
// 	vector<vector<int>> vv = {{1, 2, 3}, {2, 3, 4}, {3, 4, 5}};
// 	return vv;
// }
// void Test2(vector<vector<int>> &vv)
// {
// 	vv.push_back({1, 2, 3});
// 	vv.push_back({2, 3, 4});
// 	vv.push_back({3, 4, 5});
// }
// int main()
// {
// 	vector<vector<int>> vv1 = Test1();
// 	vector<vector<int>> vv2;
// 	Test2(vv2);
// 	return 0;
// }

#include <iostream>
using namespace std;
struct my_memory
{
	my_memory(int a = 10)
		: _size(a), _memory(new int(_size))
	{
		cout << "构造()" << endl;
	}
	my_memory(const my_memory &a)
	{
		cout << "拷贝构造(const my_mymory&a)" << endl;
		_size = a._size;
		for (int i = 0; i < _size; i++)
			_memory[i] = a._memory[i];
	}
	my_memory(my_memory &&a)
	{
		cout << "移动构造(const my_mymory&&a)" << endl;
		_size = a._size;
		int *tmp = _memory;
		_memory = a._memory; // 转移资源
		a._memory;
	}

	my_memory &operator=(my_memory &&a)
	{
		cout << "移动赋值" << endl;
		int *tmp = _memory;
		_memory = a._memory;
		a._memory = tmp;
		return *this;
	}

	int _size;
	int *_memory;
};

// int main()
// {

//         my_memory m1;
//         cout << m1._memory << endl;

//         my_memory m2;
//         m2 = move(m1);
//         cout << m2._memory << endl;
//     return 0;
// }

// #include <iostream>
// #include <vector>
// #include <queue>
// using namespace std;
// struct ListNode
// {
// 	int val;
// 	ListNode *next;
// 	ListNode() : val(0), next(nullptr) {}
// 	ListNode(int x) : val(x), next(nullptr) {}
// 	ListNode(int x, ListNode *next) : val(x), next(next) {}
// };
// struct Compare
// {
// 	bool operator()(ListNode *&l1, ListNode *&l2)
// 	{
// 		return l1->val > l2->val;
// 	}
// };

// ListNode *mergeKLists(vector<ListNode*> &lists)
// {
// 	priority_queue<ListNode *, vector<ListNode *>, Compare> pq;
// 	for (auto &list : lists)
// 	{
// 		if (list == nullptr)
// 			continue;
// 		ListNode *cur = list;
// 		ListNode *next = cur->next;
// 		while (cur != nullptr)
// 		{
// 			next = cur->next;
// 			cur->next = nullptr;
// 			pq.push(cur);
// 			cur = next;
// 		}
// 	}

// 	// 此时里面是所有链表的节点， 然后一个一个取出就行
// 	ListNode *head = new ListNode();
// 	ListNode *cur = head;
// 	while (pq.size())
// 	{
// 		ListNode *top = pq.top();
// 		pq.pop();
// 		cur->next = top;
// 		cur = top;
// 	}
// 	return head->next;
// }

// int main()
// {
// 	ListNode* head1 = new ListNode(1);
// 	head1->next = new ListNode(2);

// 	ListNode* head2 = new ListNode(3);
// 	head1->next = new ListNode(4);

// 	vector<ListNode*> v1 = {head1, head2};

// 	auto ret = mergeKLists(v1);

// 	return 0;
// }

// #include <iostream>
// #include <functional>
// using namespace std;

// int main()
// {
// 	int x = 0;
// 	const int y = 10;

// 	auto f1 = [](int x, int y) mutable
// 	{
// 		x = 10;
// 		cout << y << endl;
// 	};

// 	auto f2 = [](int x, int y) mutable
// 	{
// 		x = 12;
// 		y = 11;
// 		cout << y << endl;
// 	};

// 	function<void(int, int)> f = f1;
// 	f(x, y);
// 	f = f2;
// 	f(x, y);

// 	return 0;
// }

#include <iostream>
using namespace std;

// struct f_A
// {
// 	virtual int func() final
// 	{
// 		cout << "nihao" << endl;
// 	}
// };

// struct c_A : public f_A
// {
// 	int func()
// 	{}
// };

// struct f_A final
// {
// 	virtual int func() final
// 	{
// 		cout << "nihao" << endl;
// 	}
// };

// struct c_A : public f_A
// {

// };

// int main()
// {

// 	return 0;
// }

// struct f_A
// {
// 	virtual int func()
// 	{
// 		cout << "nihao" << endl;
// 	}
// };

// struct c_A : public f_A
// {
// 	virtual int func() override
// 	{

// 	}

// 	// virtual int func1() override
// 	// {

// 	// }

// };

// template<class T>
// void _referencesAll(T &&t)
// {
// 	cout << "你好" << endl;
// }

// int main()
// {
// 	int x = 0;
// 	_referencesAll(x);
// 	_referencesAll(move(x));

// 	return 0;
// }

// template <class... Args>
// void func1() {}

// template <typename... Args>
// void func2(const Args &...args)
// {
// 	cout << sizeof...(args) << endl;
// }

// int main()
// {
// 	func2(1, 2, 1.1, "nihao", string("nihao"));

// 	return 0;
// }

// template <class... Args>
// void func1() {}

// template <typename... Args>
// void func2(const Args &...args) // Args... 这就是一个扩展。或者理解为 ...args，这两者都表示扩展操作。
// {
// 	cout << sizeof...(args) << endl;
// }

// void print(){}

// template <class T, class... Args>
// void print(const T &t, const Args &...args) // Args... 这表示一个扩展。 参数包...
// {
// 	cout << t << endl;

// 	print(args...);     //参数包...， 表示扩展
// }

// int double_num(int x)
// {
// 	return 2 * x;
// }

// template<class... Args>
// void print_double(const Args&... args)
// {
// 	print(double_num(args)...);
// }

// int main()
// {
// 	print_double(1, 2, 3, 4, 5);
// 	return 0;
// }

// int main()
// {
// 	int a = 0;

// 	auto f1 = [a](int x)
// 	{
// 		cout << x << endl;
// 	};

// 	auto f2 = [a] (int x) mutable
// 	{
// 		a = x;
// 		cout << a << endl;
// 	};

// 	f1(10);
// 	f2(10);

// 	return 0;
// }

// #include <iostream>
// using namespace std;
// #include <unordered_map>
// #include <string>
// #include <vector>
// struct HashFunc
// {
// 	size_t operator()(const string &s1) const
// 	{
// 		size_t hash1 = 0;
// 		for (auto e : s1)
// 			hash1 += e;
// 		size_t hash2 = 1;
// 		for (auto e : s1)
// 			hash2 *= e;
// 		return (hash1 ^ (hash1 << 1)) + hash2;
// 	}
// };
// struct equal_string
// {
// 	bool operator()(const string &s1, const string &s2) const
// 	{
// 		size_t hash1 = 0;
// 		for (auto e : s1)
// 			hash1 += e;
// 		size_t hash2 = 0;
// 		for (auto e : s2)
// 			hash2 += e;
// 		return hash1 == hash2;
// 	}
// };
// class Solution
// {
// public:

// 	vector<vector<string>> groupAnagrams(vector<string> &strs)
// 	{
// 		unordered_map<string, vector<string>, HashFunc, equal_string> hash;
// 		for (auto &e : strs)
// 		{
// 			hash[e].push_back(e);
// 		}

// 		vector<vector<string>> ret;
// 		for (auto &e : hash)
// 			ret.push_back(e.second);
// 		return ret;
// 	}
// };

// int main()
// {
// 	vector<string> strs = {"eat", "tea", "tan", "ate", "nat", "bat"};
// 	Solution s1;
// 	s1.groupAnagrams(strs);
// 	return 0;
// }

// #include <iostream>
// using namespace std;
// #include <thread>

// void Print(int i)
// {
// 	for (int begin = i; begin < 100; begin++)
// 	{
// 		cout << this_thread::get_id() << ":" << begin << endl;
// 	}
// }

// int main()
// {
// 	int x = 0;
// 	const int &b = x;
// 	cout << b << endl;
// 	x = 10;
// 	cout << b << endl;

// 	auto f1 = [&x]()
// 	{
// 		cout << x << endl;
// 	};

// 	f1();

// 	return 0;
// }

// #include <iostream>
// using namespace std;
// #include <thread>
// #include <mutex>
// #include <vector>
// #include <functional>

// // function最好不要用左值引用， 因为线程的内部会让传过去的值都变成右值，这个值再让内部的线程函数去调用， 那么就调用不了。
// //
// using func_t = function<void()>;
// struct ExecuteClass
// {
// 	ExecuteClass()            //创建线程管理
// 	{}
	
// 	ExecuteClass(ExecuteClass &&ec)
// 	{
// 		func = ec.func;
// 		_id = move(ec._id);
// 	}
// 	void SetFunc(func_t f)    //设置任务
// 	{
// 		func = f;
// 	}

// 	void RunThread()      	  //直接执行任务
// 	{
// 		_id = thread(func);
// 	}

// 	~ExecuteClass()
// 	{
// 		_id.join();
// 	}
// 	func_t func;
// 	thread _id;
// };

// struct CountClass
// {
// 	CountClass(int &x)
// 		: _count(x)
// 	{
// 	}

// 	void ResizePool(size_t size)
// 	{
// 		_pool.resize(size, ExecuteClass());
// 	}

// 	void SetFunc(int i, int size)
// 	{
// 		_pool[i].SetFunc(std::bind(&CountClass::CountFunc, this, size));
// 	}

// 	void operator[](int i)
// 	{
// 		_pool[i].RunThread();
// 	}

// 	void CountFunc(int size)
// 	{
// 		while (size--) _count++;
// 	}
	
// 	std::vector<ExecuteClass> _pool;
// 	int &_count;
// 	mutex _mutex;
// };

// int main()
// {
// 	int x = 0;
// 	CountClass cc1(x);

// 	cc1.ResizePool(3);
// 	cc1.SetFunc(0, 1000);
// 	cc1.SetFunc(1, 2000);
// 	cc1.SetFunc(2, 3000);

// 	cc1[0];
// 	cc1[1];
// 	cc1[2];

// 	cout << x << endl;

// 	return 0;
// }


// #include <iostream>
// using namespace std;
// #include <thread>

// void Print(int x)
// {
// 	cout << "i am a new thread " <<  x << endl;
// }
// int main()
// {
// 	thread tid(Print, 0);  

// 	tid.join();
// 	return 0;
// }


// #include <iostream>
// using namespace std;
// #include <thread>

// void Print(int x)
// {
// 	cout << "is a new thread" << ":" << x << endl;
// }


// int main()
// {
// 	thread tid(Print, 0);
// 	thread newtid(move(tid));
// 	newtid.join();

// 	return 0;
// }



// #include <iostream>
// using namespace std;
// #include <thread>

// void Print(int x)
// {
// 	cout << "is a new thread" << ":" << x << endl;
// }


// int main()
// {
// 	thread tid(Print, 0);
	
// 	thread newtid;

// 	newtid = move(tid);
// 	newtid.join();

// 	return 0;
// }


// #include <iostream>
// using namespace std;
// #include <thread>

// void Print(int x)
// {
// 	cout << "is a new thread" << ":" << this_thread::get_id() << endl;
// }

// int main()
// {
// 	thread tid(Print, 0);

// 	cout << tid.get_id() << endl;

// 	return 0;
// }


// #include <iostream>
// using namespace std;
// #include <thread>
// #include <unistd.h>

// void Print(int x)
// {
// 	cout << "is a new thread" << ":" << this_thread::get_id() << endl;
// }

// int main()
// {
// 	thread tid(Print, 0);

// 	sleep(1);   //睡眠是为了避免和新线程发生IO冲突。
// 	cout << "tid的线程id为: " << tid.get_id() << endl;
// 	tid.detach();
// 	tid.detach();


// 	return 0;
// }



// #include <iostream>
// using namespace std;
// #include <thread>
// #include <unistd.h>

// void Print(int x)
// {
// 	cout << "is a new thread" << ":" << this_thread::get_id() << endl;
// }

// int main()
// {
// 	thread t1(Print, 0);
// 	thread t2(Print, 0);
// 	sleep(1);  //防止IO冲突

// 	cout << "t1.id: " << t1.get_id() << " : " << "t2.id: " << t2.get_id() << endl;
	
	
// 	swap(t1, t2);
// 	cout << "t1.id: " << t1.get_id() << " : " << "t2.id: " << t2.get_id() << endl;


// 	t1.join();
// 	t2.join();
// 	return 0;
// }


// #include <iostream>
// using namespace std;
// #include <mutex>
// #include <thread>
// #include <unistd.h>

// void Print(mutex &m)
// {
// 	cout << "is a new thread" << ":" << this_thread::get_id() << endl;
// }

// int main()
// {
// 	mutex m;

// 	thread t1(Print, ref(m));
// 	thread t2(Print, ref(m));

// 	t1.join();
// 	t2.join();

// 	return 0;
// }


// #include <iostream>
// using namespace std;
// #include <mutex>
// #include <thread>
// #include <unistd.h>

// void Print(mutex &m)
// {
// 	if (m.try_lock())
// 	{
// 		sleep(2);   //模拟工作线程
// 		cout << "is a new thread" << ":" << this_thread::get_id() << endl;

// 		m.unlock();
// 	}
// 	else
// 	{
// 		cout << this_thread::get_id() << "获取锁失败， 返回" << endl;
// 	}
// }

// int main()
// {
// 	mutex m;

// 	thread t1(Print, ref(m));
// 	thread t2(Print, ref(m));

// 	t1.join();
// 	t2.join();

// 	return 0;
// }



// #include <iostream>
// using namespace std;
// #include <mutex>
// #include <thread>
// #include <unistd.h>


// void Print(recursive_mutex &m, int &lock_count, int &unlock_count)
// {
// 	if (lock_count >= 10) return;
// 	m.lock();
// 	cout << "get a lock: " << lock_count++ << endl;
// 	sleep(1); //防止打印过快
// 	Print(m, lock_count, unlock_count);


// 	cout << "unlock: " << unlock_count++ << endl;
// }

// int main()
// {
// 	recursive_mutex m;
// 	int lock_count = 0;
// 	int unlock_count = 0;

// 	thread t1(Print, ref(m), ref(lock_count), ref(unlock_count));

// 	t1.join();
	
// 	cout << "lock_count:" << lock_count << endl;
// 	cout << "unlock_count:" << unlock_count << endl; 
// 	return 0;
// }

// #include <iostream>
// using namespace std;
// #include <mutex>
// #include <thread>
// #include <unistd.h>


// void Print(timed_mutex &m)
// {
// 	if (m.try_lock_for(std::chrono::milliseconds(2000)))
// 	{
// 		cout << this_thread::get_id() << " get a lock" <<endl;
// 		sleep(1);
// 		m.unlock();
// 	}
// 	else 
// 	{
// 		cout << this_thread::get_id() << " not get a lock" << endl;
// 	}

// }

// int main()
// {
// 	timed_mutex m;

// 	thread t1(Print, ref(m));
// 	thread t2(Print, ref(m));


// 	t1.join();
// 	t2.join();

// 	return 0;
// }

// #include <iostream>
// using namespace std;
// #include <mutex>
// #include <thread>
// #include <unistd.h>


// void Print(timed_mutex &m)
// {
// 	if (m.try_lock_until(std::chrono::steady_clock::now() + std::chrono::milliseconds(2000)))
// 	{
// 		cout << this_thread::get_id() << " get a lock" <<endl;
// 		sleep(1);
// 		m.unlock();
// 	}
// 	else 
// 	{
// 		cout << this_thread::get_id() << " not get a lock" << endl;
// 	}

// }

// int main()
// {
// 	timed_mutex m;

// 	thread t1(Print, ref(m));
// 	thread t2(Print, ref(m));


// 	t1.join();
// 	t2.join();

// 	return 0;
// }



// #include <iostream>
// using namespace std;
// #include <mutex>
// #include <thread>
// #include <unistd.h>


// void Print(mutex &m)
// {
// 	lock_guard<mutex> lock(m);
// 	cout << this_thread::get_id() << " get a lock" <<endl;
// }

// int main()
// {
// 	mutex m;

// 	thread t1(Print, ref(m));
// 	thread t2(Print, ref(m));


// 	t1.join();
// 	t2.join();

// 	return 0;
// }
// #include <iostream>
// using namespace std;
// #include <mutex>
// #include <thread>
// #include <unistd.h>


// void Print(mutex &m)
// {
// 	unique_lock<mutex> lock(m);
// 	cout << this_thread::get_id() << " get a lock" <<endl;

// 	lock.unlock();

// 	lock.lock();
// 	cout << this_thread::get_id() << " again get a lock" <<endl;


// }

// int main()
// {
// 	mutex m;

// 	thread t1(Print, ref(m));
// 	thread t2(Print, ref(m));


// 	t1.join();
// 	t2.join();

// 	return 0;
// }